const favicons = require('favicons');
const path = require('path');
const fs = require('fs');
const _ = require('lodash');
const findUp = require('find-up');

const defaultIcon = `
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
    xmlns="http://www.w3.org/2000/svg">
    <path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
</svg>`;

const defaultOptions = {
	icon: 'public/vercel.svg', // you icon path
	component: 'components/ui/favicon.tsx', // you component path
	output: 'public', // favicons out path
	favicons: {
		path: '/favicons/', // Path for overriding default icons path. `string`
		appName: 'name', // Your application's name. `string`
		appShortName: 'name', // Your application's short_name. `string`. Optional. If not set, appName will be used
		appDescription: 'desc', // Your application's description. `string`
		developerName: 'auth', // Your (or your developer's) name. `string`
		developerURL: 'domain.me', // Your (or your developer's) URL. `string`
		dir: 'auto', // Primary text direction for name, short_name, and description
		lang: 'zh-CN', // Primary language for name and short_name
		background: '#fff', // Background colour for flattened icons. `string`
		theme_color: '#fff', // Theme color user for example in Android's task switcher. `string`
		appleStatusBarStyle: 'black-translucent', // Style for Apple status bar: "black-translucent", "default", "black". `string`
		display: 'standalone', // Preferred display mode: "fullscreen", "standalone", "minimal-ui" or "browser". `string`
		orientation: 'any', // Default orientation: "any", "natural", "portrait" or "landscape". `string`
		scope: '/', // set of URLs that the browser considers within your app
		start_url: '/?app=1', // Start URL when launching the application from a device. `string`
		version: '1.0', // Your application's version string. `string`
		logging: false, // Print logs to console? `boolean`
		pixel_art: false, // Keeps pixels "sharp" when scaling up, for pixel art.  Only supported in offline mode.
		loadManifestWithCredentials: false, // Browsers don't send cookies when fetching a manifest, enable this to fix that. `boolean`
		icons: {
			android: true, // Create Android homescreen icon. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources
			appleIcon: true, // Create Apple touch icons. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources
			appleStartup: true, // Create Apple startup images. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources
			coast: true, // Create Opera Coast icon. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources
			favicons: true, // Create regular favicons. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources
			firefox: true, // Create Firefox OS icons. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources
			windows: true, // Create Windows 8 tile icons. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources
			yandex: true, // Create Yandex browser icon. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources
		},
	},
};

// you can change next line function, make to vue or angular component!!!
function getJsx(type) {
	if (type === 'typescript') {
		return `
import React from 'react';
export const MetaFavicons:React.FC<unknown> = () =>{
  return <>
REPLACE_TEXT
  </>
}
export default MetaFavicons
	  `;
	}
	return `
import React from 'react';
export const MetaFavicons = () =>{
  return <>
REPLACE_TEXT
  </>
}
export default MetaFavicons
	`;
}

(async options => {
	console.log('start make favicons');
	const basePath = await findUp(
		async directory => {
			const hasUnicorns = await findUp.exists(path.join(directory, 'next.config.js'));
			return hasUnicorns && directory;
		},
		{ type: 'directory' },
	);

	console.log(`your next project path is ${basePath}`);

	let mergeOption = _.merge(defaultOptions, options);
	mergeOption = _.merge(mergeOption, {
		icon: path.resolve(path.join(basePath, mergeOption.icon)),
		component: path.resolve(path.join(basePath, mergeOption.component)),
	});

	const iconIsTypescriptComponent = mergeOption.icon.includes('tsx');

	if (!fs.existsSync(mergeOption.icon)) {
		console.log('write default icon');
		fs.writeFileSync(mergeOption.icon, defaultIcon);
	}

	console.log('make favicons...');
	const response = await new favicons(mergeOption.icon, mergeOption.favicons);
	console.log('make success');
	const fileOutput = path.join(basePath, mergeOption.output, mergeOption.favicons.path);

	if (!fs.existsSync(fileOutput)) {
		fs.mkdirSync(fileOutput);
	}

	const allFiles = [...response.images, ...response.files];

	console.log('write files:', allFiles.length);
	allFiles.forEach(({ name, contents }) => {
		fs.writeFileSync(path.join(fileOutput, name), contents);
	});

	console.log('write component');
	const rawTemplate = getJsx(iconIsTypescriptComponent ? 'typescript' : 'javascript');
	const rawTemplateStr = response.html.map(i => `\t\t\t\t${i}`).join('\n');
	const closeTemplateTag = rawTemplateStr.split('>').join(' />');
	const template = rawTemplate.replace('REPLACE_TEXT', closeTemplateTag);
	fs.writeFileSync(mergeOption.component, template);

	console.log('execute success');
})();